import re

from aiogram import Bot, F, Router, types
from aiogram.fsm.context import FSMContext
from aiogram.types import BufferedInputFile, FSInputFile, ReplyKeyboardRemove

from src.bot.keyboards.inline import (
    buy_document_btn,
    continue_btn,
    select_data_to_change,
)
from src.bot.keyboards.reply import (
    COUNTRIES,
    DOCUMENTS_TYPES,
    back_btn,
    back_with_skip_btn,
    countries_kb,
    document_type_kb,
    skip_btn,
)
from src.bot.services.generators import format_user_bill_data
from src.bot.services.helpers import check_if_text_is_english
from src.bot.services.pdf.uk import UKPDFService
from src.bot.services.tg_helpers import save_msg_delete
from src.bot.states import TestSG

create_doc_router = Router()


async def send_watermarked_document(
    message: types.Message, bot: Bot, state: FSMContext
):
    """Отправляем документ с ватермаркой"""

    data = await state.get_data()
    msg = await message.answer(
        "Ожидайте генерируется...", reply_markup=ReplyKeyboardRemove()
    )
    pdf_service = UKPDFService()
    generated_file = pdf_service.create_uk_bill(
        data.get("first_name"),
        data.get("last_name"),
        data.get("street_name"),
        data.get("city_name"),
        data.get("postal_code"),
        with_watermark=True,
    )
    await message.answer_document(
        BufferedInputFile(generated_file, "uk_bill_watermark.pdf"),
        caption="Завершите покупку документа.",
        reply_markup=buy_document_btn(),
    )
    await save_msg_delete(bot, message.chat.id, msg.message_id)


async def send_back_msg(message: types.Message, bot: Bot, state: FSMContext):
    """Отправляем сообщение для предыдущего State"""

    state_name = await state.get_state()
    reply_markup = back_btn()
    if state_name == "TestSG:enter_last_name":
        await state.update_data(first_name=None)
        await state.set_state(TestSG.enter_first_name)
    elif state_name == "TestSG:enter_house_num":
        await state.update_data(last_name=None)
        await state.set_state(TestSG.enter_last_name)
    elif state_name == "TestSG:enter_street_name":
        reply_markup = back_with_skip_btn()
        await state.update_data(house_num=None)
        await state.set_state(TestSG.enter_house_num)
    elif state_name == "TestSG:enter_city_name":
        await state.update_data(street_name=None)
        await state.set_state(TestSG.enter_street_name)
    elif state_name == "TestSG:enter_postal_code":
        await state.update_data(city_name=None)
        await state.set_state(TestSG.enter_city_name)

    data = await state.get_data()
    txt = format_user_bill_data(data)
    await save_msg_delete(bot, message.chat.id, data.get("msg_id"))
    msg = await message.answer(txt, reply_markup=reply_markup)
    await state.update_data(msg_id=msg.message_id)


async def send_next_msg(message: types.Message, bot: Bot, state: FSMContext):
    """Отправляем сообщение для следующего State"""

    state_name = await state.get_state()
    reply_markup = back_btn()
    if state_name == "TestSG:enter_first_name":
        await state.set_state(TestSG.enter_last_name)
    elif state_name == "TestSG:enter_last_name":
        reply_markup = back_with_skip_btn()
        await state.set_state(TestSG.enter_house_num)
    elif state_name == "TestSG:enter_house_num":
        await state.set_state(TestSG.enter_street_name)
    elif state_name == "TestSG:enter_street_name":
        await state.set_state(TestSG.enter_city_name)
    elif state_name == "TestSG:enter_city_name":
        await state.set_state(TestSG.enter_postal_code)

    data = await state.get_data()
    txt = format_user_bill_data(data)
    if "Введите" not in txt:
        await send_watermarked_document(message, bot, state)
    else:
        await save_msg_delete(bot, message.chat.id, data.get("msg_id"))
        msg = await message.answer(txt, reply_markup=reply_markup)
        await state.update_data(msg_id=msg.message_id)


@create_doc_router.message(F.text == "Создать документ")
async def select_country_msg(message: types.Message, state: FSMContext):
    txt = (
        "❗️ Внимание ❗️ \n\n"
        "Оказанные услуги, несут развлекательный, ознакомительный и общий характер, без нарушения статей закона УК РФ, Статья 327; УК РФ, Статья 292; УК РФ, Статья 159 и Статья 137 УК РФ.\n"
        "Администрация не несёт ответственности за использование материала\n\n"
        "❗️ Нажимая кнопку 'Продолжить' вы принимаете все риски и ответственность за использование материала. ❗️\n\n"
        "🏷 price:\n"
        "<b>- Pass, ID - 7 usdt;</b>\n"
        "<b>- Bill - 5 usdt.</b>"
    )
    await state.set_state(TestSG.accept_policy)
    msg = await message.answer(txt, reply_markup=continue_btn())
    await state.update_data(msg_id=msg.message_id)


@create_doc_router.callback_query(TestSG.accept_policy, F.data == "continue")
@create_doc_router.message(F.text == "Назад ◀️", TestSG.select_document_type)
async def accept_policy(message: types.CallbackQuery, bot: Bot, state: FSMContext):
    data = await state.get_data()
    if isinstance(message, types.CallbackQuery):
        await message.message.answer("Выберите страну", reply_markup=countries_kb())
        await save_msg_delete(bot, message.from_user.id, data.get("msg_id"))
    else:
        await message.answer("Выберите страну", reply_markup=countries_kb())
    await state.set_state(TestSG.select_country)


@create_doc_router.message(TestSG.select_country, F.text.in_(COUNTRIES))
@create_doc_router.message(F.text == "Назад ◀️", TestSG.enter_first_name)
async def select_country_msg(message: types.Message, state: FSMContext):
    await state.update_data(country=message.text)
    await state.set_state(TestSG.select_document_type)
    await message.answer(
        "Выберите документ для создания", reply_markup=document_type_kb()
    )


@create_doc_router.message(TestSG.select_document_type, F.text.in_(DOCUMENTS_TYPES))
async def select_doc_type_msg(message: types.Message, state: FSMContext):
    await state.update_data(doc_type=message.text)
    data = await state.get_data()
    txt = format_user_bill_data(data)
    await message.answer_photo(FSInputFile("src/bot/media/uk_bill_example.jpg"))
    await state.set_state(TestSG.enter_first_name)
    msg = await message.answer(txt, reply_markup=back_btn())
    await state.update_data(msg_id=msg.message_id)


@create_doc_router.message(TestSG.enter_first_name)
@create_doc_router.message(F.text == "Назад ◀️", TestSG.enter_last_name)
async def enter_first_name(message: types.Message, bot: Bot, state: FSMContext):
    await message.delete()
    if message.text == "Назад ◀️":
        await send_back_msg(message, bot, state)
    else:
        if check_if_text_is_english(message.text):
            await state.update_data(first_name=message.text)
        else:
            await message.answer(
                "❌ Введите имя в правильном формате.\nФормат: латинские буквы"
            )
            return

        await send_next_msg(message, bot, state)


@create_doc_router.message(TestSG.enter_last_name)
@create_doc_router.message(F.text == "Назад ◀️", TestSG.enter_house_num)
async def enter_last_name(message: types.Message, bot: Bot, state: FSMContext):
    await message.delete()
    if message.text == "Назад ◀️":
        await send_back_msg(message, bot, state)
    else:
        if check_if_text_is_english(message.text):
            await state.update_data(last_name=message.text)
        else:
            await message.answer(
                "❌ Введите фамилию в правильном формате.\nФормат: латинские буквы"
            )
            return

        await send_next_msg(message, bot, state)


@create_doc_router.message(TestSG.enter_house_num)
@create_doc_router.message(F.text == "Назад ◀️", TestSG.enter_street_name)
async def enter_house_num(message: types.Message, bot: Bot, state: FSMContext):
    await message.delete()
    if message.text == "Назад ◀️":
        await send_back_msg(message, bot, state)

    else:
        if message.text == "Пропустить":
            await state.update_data(house_num="")
        else:
            if message.text.isdigit():
                await state.update_data(house_num=message.text)
            else:
                await message.answer(
                    "❌ Введите номер дома в правильном формате.\nФормат: цифры"
                )
                return

        await send_next_msg(message, bot, state)


@create_doc_router.message(TestSG.enter_street_name)
@create_doc_router.message(F.text == "Назад ◀️", TestSG.enter_city_name)
async def enter_street_name(message: types.Message, bot: Bot, state: FSMContext):
    await message.delete()
    if message.text == "Назад ◀️":
        await send_back_msg(message, bot, state)
    else:
        await state.update_data(street_name=message.text)
        await send_next_msg(message, bot, state)


@create_doc_router.message(TestSG.enter_city_name)
@create_doc_router.message(F.text == "Назад ◀️", TestSG.enter_postal_code)
async def enter_city_name(message: types.Message, bot: Bot, state: FSMContext):
    await message.delete()
    if message.text == "Назад ◀️":
        await send_back_msg(message, bot, state)
    else:
        if check_if_text_is_english(message.text):
            await state.update_data(city_name=message.text)
        else:
            await message.answer(
                "❌ Введите название города в правильном формате.\nФормат: латинские буквы"
            )
            return

        await send_next_msg(message, bot, state)


@create_doc_router.message(TestSG.enter_postal_code)
async def enter_city_name(message: types.Message, bot: Bot, state: FSMContext):
    await message.delete()
    if message.text == "Назад ◀️":
        await send_back_msg(message, bot, state)
    else:
        if re.match("[0-9A-Z]", message.text):
            await state.update_data(postal_code=message.text)
        else:
            await message.answer(
                "❌ Введите посткод в правильном формате.\nФормат: цифры и латинские буквы"
            )
            return

        data = await state.get_data()
        await save_msg_delete(bot, message.chat.id, data.get("msg_id"))

        await send_watermarked_document(message, bot, state)


@create_doc_router.callback_query(F.data == "buy_document")
async def buy_document(call: types.CallbackQuery, state: FSMContext):
    data = await state.get_data()

    pdf_service = UKPDFService()
    generated_file = pdf_service.create_uk_bill(
        data.get("first_name"),
        data.get("last_name"),
        data.get("street_name"),
        data.get("city_name"),
        data.get("postal_code"),
    )

    await call.message.answer("Ожидайте генерируется...")
    # await call.message.delete()
    await call.message.answer_document(
        BufferedInputFile(generated_file, "uk_bill.pdf"),
        reply_markup=ReplyKeyboardRemove(),
    )

    # await state.clear()


@create_doc_router.callback_query(F.data == "change_document")
async def change_document(call: types.CallbackQuery):
    await call.message.delete()
    await call.message.answer(
        "Выберите, что хотите заменить", reply_markup=select_data_to_change()
    )


@create_doc_router.callback_query(F.data == "change_first_name")
async def change_first_name(call: types.CallbackQuery, state: FSMContext):
    await call.message.delete()
    await call.message.answer("Введите новое имя")
    await state.set_state(TestSG.enter_first_name)


@create_doc_router.callback_query(F.data == "change_last_name")
async def change_last_name(call: types.CallbackQuery, state: FSMContext):
    await call.message.delete()
    await call.message.answer("Введите новую фамилию")
    await state.set_state(TestSG.enter_last_name)


@create_doc_router.callback_query(F.data == "change_house_num")
async def change_house_num(call: types.CallbackQuery, state: FSMContext):
    await call.message.delete()
    await call.message.answer("Введите новый номер дома", reply_markup=skip_btn())
    await state.set_state(TestSG.enter_house_num)


@create_doc_router.callback_query(F.data == "change_street_name")
async def change_street_name(call: types.CallbackQuery, state: FSMContext):
    await call.message.delete()
    await call.message.answer("Введите новое название улицы")
    await state.set_state(TestSG.enter_street_name)


@create_doc_router.callback_query(F.data == "change_city_name")
async def change_city_name(call: types.CallbackQuery, state: FSMContext):
    await call.message.delete()
    await call.message.answer("Введите новое название города")
    await state.set_state(TestSG.enter_city_name)


@create_doc_router.callback_query(F.data == "change_post_code")
async def change_post_code(call: types.CallbackQuery, state: FSMContext):
    await call.message.delete()
    await call.message.answer("Введите новый посткод")
    await state.set_state(TestSG.enter_postal_code)
